package com.gas.gm.pdu.session;

import java.io.IOException;

import org.apache.log4j.Logger;

import com.gas.gm.pdu.DataProcessor;
import com.logica.smpp.Connection;
import com.logica.smpp.Data;
import com.logica.smpp.Receiver;
import com.logica.smpp.Transmitter;
import com.logica.smpp.pdu.PDU;
import com.logica.smpp.pdu.Request;
import com.logica.smpp.pdu.Response;
import com.logica.smpp.pdu.ValueNotSetException;

public class GasGmSession implements Runnable {

	private static final Logger logger = Logger.getLogger(GasGmSession.class);

	private Receiver receiver;
	private Transmitter transmitter;
	private DataProcessor processor;
	private Connection connection;
	private long receiverTimeout = Data.RECEIVER_TIMEOUT;
	private boolean alive = true;
	private boolean receiving = false;

	public GasGmSession(Connection connection) {
		this.connection = connection;
		this.transmitter = new Transmitter(connection);
		this.receiver = new Receiver(transmitter, connection);
	}

	public void stop() {
		logger.info("stop session");
		alive = false;
	}

	public void sendPdu(PDU pdu) {
		try {
			logger.info("session will send pdu");
			transmitter.send(pdu);
			logger.info("pdu sent: " + pdu.debugString());
		} catch (ValueNotSetException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void run() {
		PDU pdu = null;

		logger.info("session starting...");
		receiver.start();
		logger.info("session start receiving...");
		receiving = true;

		try {
			while (alive) {
				try {
					logger.info("session will receive pdu");
					pdu = receiver.receive(getReceiverTimeout());
				} catch (Exception e) {
					logger.debug("exception when receiving a pdu "
							+ e.getMessage());
				}

				if (pdu != null) {
					if (pdu.isRequest()) {
						logger.info("session accepting pdu request: "
								+ pdu.debugString());
						processor.processRequest((Request) pdu);
					} else if (pdu.isResponse()) {
						logger.info("session accepting pdu response: "
								+ pdu.debugString());
						processor.processResponse((Response) pdu);
					} else {
						logger.info("session nganggur");
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			receiving = false;
		}
		logger.info("session stoping receiver...");
		stop();
		logger.info("session exiting pdu processor");
		processor.exit();
		try {
			logger.info("clossing connection: ");
			connection.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public long getReceiverTimeout() {
		return receiverTimeout;
	}

	public void setProcessor(DataProcessor processor) {
		this.processor = processor;
	}

	public boolean isReceiving() {
		return receiving;
	}

}
